package org.convallaria.system.biz.util;

import lombok.extern.slf4j.Slf4j;
import org.convallaria.system.biz.service.SecurityConfigService;
import org.convallaria.system.biz.service.PerformanceMonitorService;
import org.convallaria.system.biz.service.CacheOptimizationService;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 文档生成工具类
 * 
 * @author convallaria
 * @since 1.0.0
 */
@Slf4j
@Component
public class DocumentationGenerator {

    /**
     * 生成系统配置文档
     * 
     * @param securityConfigService 安全配置服务
     * @return 配置文档
     */
    public String generateConfigurationDocument(SecurityConfigService securityConfigService) {
        StringBuilder doc = new StringBuilder();
        
        doc.append("# 系统配置文档\n\n");
        doc.append("生成时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");
        
        // 安全配置
        doc.append("## 安全配置\n\n");
        SecurityConfigService.SecurityConfig securityConfig = securityConfigService.getSecurityConfig();
        doc.append("- 验证码启用: ").append(securityConfig.isEnableCaptcha()).append("\n");
        doc.append("- 登录限制启用: ").append(securityConfig.isEnableLoginLimit()).append("\n");
        doc.append("- 密码策略启用: ").append(securityConfig.isEnablePasswordPolicy()).append("\n");
        doc.append("- 审计日志启用: ").append(securityConfig.isEnableAuditLog()).append("\n");
        doc.append("- Token黑名单启用: ").append(securityConfig.isEnableTokenBlacklist()).append("\n");
        doc.append("- 设备指纹启用: ").append(securityConfig.isEnableDeviceFingerprint()).append("\n");
        doc.append("- 行为分析启用: ").append(securityConfig.isEnableBehaviorAnalysis()).append("\n");
        doc.append("- 会话超时: ").append(securityConfig.getSessionTimeout()).append("\n");
        doc.append("- 最大并发会话: ").append(securityConfig.getMaxConcurrentSessions()).append("\n\n");
        
        // 密码策略配置
        doc.append("## 密码策略配置\n\n");
        SecurityConfigService.PasswordPolicyConfig passwordConfig = securityConfigService.getPasswordPolicyConfig();
        doc.append("- 最小长度: ").append(passwordConfig.getMinLength()).append("\n");
        doc.append("- 最大长度: ").append(passwordConfig.getMaxLength()).append("\n");
        doc.append("- 需要小写字母: ").append(passwordConfig.isRequireLowercase()).append("\n");
        doc.append("- 需要大写字母: ").append(passwordConfig.isRequireUppercase()).append("\n");
        doc.append("- 需要数字: ").append(passwordConfig.isRequireDigit()).append("\n");
        doc.append("- 需要特殊字符: ").append(passwordConfig.isRequireSpecialChar()).append("\n");
        doc.append("- 历史密码数量: ").append(passwordConfig.getHistoryCount()).append("\n");
        doc.append("- 检查常见密码: ").append(passwordConfig.isCheckCommonPasswords()).append("\n");
        doc.append("- 检查用户名: ").append(passwordConfig.isCheckUsername()).append("\n");
        doc.append("- 检查个人信息: ").append(passwordConfig.isCheckPersonalInfo()).append("\n");
        doc.append("- 密码过期天数: ").append(passwordConfig.getPasswordExpireDays()).append("\n");
        doc.append("- 密码警告天数: ").append(passwordConfig.getPasswordWarnDays()).append("\n\n");
        
        // 登录限制配置
        doc.append("## 登录限制配置\n\n");
        SecurityConfigService.LoginLimitConfig loginConfig = securityConfigService.getLoginLimitConfig();
        doc.append("- 最大尝试次数: ").append(loginConfig.getMaxAttempts()).append("\n");
        doc.append("- 锁定时间: ").append(loginConfig.getLockTime()).append("\n");
        doc.append("- 尝试窗口: ").append(loginConfig.getAttemptWindow()).append("\n");
        doc.append("- IP锁定启用: ").append(loginConfig.isEnableIpLock()).append("\n");
        doc.append("- 账户锁定启用: ").append(loginConfig.isEnableAccountLock()).append("\n");
        doc.append("- 最大IP尝试次数: ").append(loginConfig.getMaxIpAttempts()).append("\n");
        doc.append("- IP锁定时间: ").append(loginConfig.getIpLockTime()).append("\n\n");
        
        // Token配置
        doc.append("## Token配置\n\n");
        SecurityConfigService.TokenConfig tokenConfig = securityConfigService.getTokenConfig();
        doc.append("- 访问Token过期时间: ").append(tokenConfig.getAccessTokenExpire()).append("\n");
        doc.append("- 刷新Token过期时间: ").append(tokenConfig.getRefreshTokenExpire()).append("\n");
        doc.append("- 刷新Token启用: ").append(tokenConfig.isEnableRefreshToken()).append("\n");
        doc.append("- Token黑名单启用: ").append(tokenConfig.isEnableTokenBlacklist()).append("\n");
        doc.append("- 最大刷新次数: ").append(tokenConfig.getMaxRefreshCount()).append("\n");
        doc.append("- 黑名单过期时间: ").append(tokenConfig.getBlacklistExpire()).append("\n\n");
        
        return doc.toString();
    }

    /**
     * 生成性能监控文档
     * 
     * @param performanceMonitorService 性能监控服务
     * @return 性能监控文档
     */
    public String generatePerformanceDocument(PerformanceMonitorService performanceMonitorService) {
        StringBuilder doc = new StringBuilder();
        
        doc.append("# 性能监控文档\n\n");
        doc.append("生成时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");
        
        // 性能统计
        doc.append("## 性能统计\n\n");
        PerformanceMonitorService.PerformanceStatistics stats = performanceMonitorService.getPerformanceStatistics(24);
        doc.append("- 总请求数: ").append(stats.getTotalRequests()).append("\n");
        doc.append("- 成功请求数: ").append(stats.getSuccessfulRequests()).append("\n");
        doc.append("- 失败请求数: ").append(stats.getFailedRequests()).append("\n");
        doc.append("- 成功率: ").append(String.format("%.2f%%", stats.getSuccessRate() * 100)).append("\n");
        doc.append("- 平均响应时间: ").append(String.format("%.2fms", stats.getAverageResponseTime())).append("\n");
        doc.append("- P95响应时间: ").append(String.format("%.2fms", stats.getP95ResponseTime())).append("\n");
        doc.append("- P99响应时间: ").append(String.format("%.2fms", stats.getP99ResponseTime())).append("\n");
        doc.append("- 慢操作数: ").append(stats.getSlowOperations()).append("\n\n");
        
        // 系统资源使用情况
        doc.append("## 系统资源使用情况\n\n");
        PerformanceMonitorService.SystemResourceUsage resources = performanceMonitorService.getSystemResourceUsage();
        doc.append("- CPU使用率: ").append(String.format("%.2f%%", resources.getCpuUsage())).append("\n");
        doc.append("- 内存使用: ").append(formatBytes(resources.getMemoryUsed())).append(" / ").append(formatBytes(resources.getMemoryTotal())).append("\n");
        doc.append("- 内存使用率: ").append(String.format("%.2f%%", resources.getMemoryUsagePercent())).append("\n");
        doc.append("- 磁盘使用: ").append(formatBytes(resources.getDiskUsed())).append(" / ").append(formatBytes(resources.getDiskTotal())).append("\n");
        doc.append("- 磁盘使用率: ").append(String.format("%.2f%%", resources.getDiskUsagePercent())).append("\n");
        doc.append("- 活跃连接: ").append(resources.getActiveConnections()).append(" / ").append(resources.getMaxConnections()).append("\n");
        doc.append("- 连接使用率: ").append(String.format("%.2f%%", resources.getConnectionUsagePercent())).append("\n\n");
        
        return doc.toString();
    }

    /**
     * 生成缓存优化文档
     * 
     * @param cacheOptimizationService 缓存优化服务
     * @return 缓存优化文档
     */
    public String generateCacheDocument(CacheOptimizationService cacheOptimizationService) {
        StringBuilder doc = new StringBuilder();
        
        doc.append("# 缓存优化文档\n\n");
        doc.append("生成时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");
        
        // 缓存统计
        doc.append("## 缓存统计\n\n");
        CacheOptimizationService.CacheStatistics stats = cacheOptimizationService.getCacheStatistics();
        doc.append("- 总键数: ").append(stats.getTotalKeys()).append("\n");
        doc.append("- 命中次数: ").append(stats.getHitCount()).append("\n");
        doc.append("- 未命中次数: ").append(stats.getMissCount()).append("\n");
        doc.append("- 命中率: ").append(String.format("%.2f%%", stats.getHitRate() * 100)).append("\n");
        doc.append("- 内存使用: ").append(formatBytes(stats.getMemoryUsage())).append("\n");
        doc.append("- 最大内存: ").append(formatBytes(stats.getMaxMemory())).append("\n\n");
        
        // 热门键
        doc.append("## 热门键\n\n");
        if (stats.getTopKeys() != null && !stats.getTopKeys().isEmpty()) {
            doc.append("| 键名 | 类型 | 访问次数 | 内存大小 | TTL |\n");
            doc.append("|------|------|----------|----------|-----|\n");
            for (CacheOptimizationService.CacheKeyInfo keyInfo : stats.getTopKeys()) {
                doc.append("| ").append(keyInfo.getKey())
                   .append(" | ").append(keyInfo.getType())
                   .append(" | ").append(keyInfo.getAccessCount())
                   .append(" | ").append(formatBytes(keyInfo.getMemorySize()))
                   .append(" | ").append(keyInfo.getTtl())
                   .append(" |\n");
            }
        } else {
            doc.append("暂无热门键数据\n");
        }
        
        return doc.toString();
    }

    /**
     * 生成API文档
     * 
     * @return API文档
     */
    public String generateApiDocument() {
        StringBuilder doc = new StringBuilder();
        
        doc.append("# API接口文档\n\n");
        doc.append("生成时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");
        
        // 认证接口
        doc.append("## 认证接口\n\n");
        doc.append("### 用户登录\n");
        doc.append("- **URL**: `POST /auth/login`\n");
        doc.append("- **描述**: 用户通过用户名密码登录系统\n");
        doc.append("- **请求参数**:\n");
        doc.append("  - `username`: 用户名\n");
        doc.append("  - `password`: 密码\n");
        doc.append("  - `captcha`: 验证码（可选）\n");
        doc.append("  - `captchaKey`: 验证码键（可选）\n");
        doc.append("- **响应**: Token信息\n\n");
        
        doc.append("### 用户登出\n");
        doc.append("- **URL**: `POST /auth/logout`\n");
        doc.append("- **描述**: 用户登出系统\n");
        doc.append("- **请求头**: `Authorization: Bearer <token>`\n");
        doc.append("- **响应**: 成功消息\n\n");
        
        doc.append("### 刷新Token\n");
        doc.append("- **URL**: `POST /auth/refresh`\n");
        doc.append("- **描述**: 刷新访问Token\n");
        doc.append("- **请求参数**: `refreshToken`\n");
        doc.append("- **响应**: 新的Token信息\n\n");
        
        // 安全监控接口
        doc.append("## 安全监控接口\n\n");
        doc.append("### 获取安全概览\n");
        doc.append("- **URL**: `GET /security/monitor/overview`\n");
        doc.append("- **描述**: 获取系统安全状态概览\n");
        doc.append("- **权限**: `system:security:monitor`\n");
        doc.append("- **响应**: 安全概览信息\n\n");
        
        // 性能监控接口
        doc.append("## 性能监控接口\n\n");
        doc.append("### 获取性能统计\n");
        doc.append("- **URL**: `GET /performance/statistics`\n");
        doc.append("- **描述**: 获取系统性能统计信息\n");
        doc.append("- **权限**: `system:performance:monitor`\n");
        doc.append("- **响应**: 性能统计信息\n\n");
        
        return doc.toString();
    }

    /**
     * 生成完整系统文档
     * 
     * @param securityConfigService 安全配置服务
     * @param performanceMonitorService 性能监控服务
     * @param cacheOptimizationService 缓存优化服务
     * @return 完整系统文档
     */
    public String generateCompleteDocument(SecurityConfigService securityConfigService,
                                         PerformanceMonitorService performanceMonitorService,
                                         CacheOptimizationService cacheOptimizationService) {
        StringBuilder doc = new StringBuilder();
        
        doc.append("# Convallaria 认证管理系统文档\n\n");
        doc.append("版本: 1.0.0\n");
        doc.append("生成时间: ").append(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)).append("\n\n");
        
        doc.append("## 目录\n\n");
        doc.append("1. [系统配置](#系统配置)\n");
        doc.append("2. [性能监控](#性能监控)\n");
        doc.append("3. [缓存优化](#缓存优化)\n");
        doc.append("4. [API接口](#api接口)\n\n");
        
        doc.append(generateConfigurationDocument(securityConfigService));
        doc.append(generatePerformanceDocument(performanceMonitorService));
        doc.append(generateCacheDocument(cacheOptimizationService));
        doc.append(generateApiDocument());
        
        return doc.toString();
    }

    /**
     * 格式化字节数
     */
    private String formatBytes(long bytes) {
        if (bytes < 1024) return bytes + " B";
        if (bytes < 1024 * 1024) return String.format("%.2f KB", bytes / 1024.0);
        if (bytes < 1024 * 1024 * 1024) return String.format("%.2f MB", bytes / (1024.0 * 1024.0));
        return String.format("%.2f GB", bytes / (1024.0 * 1024.0 * 1024.0));
    }
}
